package com.wandian.game.sound
{
	import com.wandian.assets.AssetsLibrary;
	
	import flash.events.*;
	import flash.media.*;
	import flash.utils.*;

	public class SoundEx extends EventDispatcher
	{
		private var fAuxiliarySoundsProbabilities_num_arr:Array;
		private var fDefaultPlayOffsetInMs_num:Number;
		private var fSoundOn_bl:Boolean;
		private var fAuxiliarySounds_sndex_arr:Array;
		private var fSoundId_str:String;
		private var fChannels_sche_arr:Array;
		private var fSound_snd:Sound;
		private var fDefaultVolume_num:Number;
		public static const EVENT_SOUND_PLAYING_COMPLETED:String="onSoundPlayingCompleted";

		public function SoundEx(param1:String, param2:Number=1, param3:Number=0)
		{
			var aSoundId_str:*=param1;
			var aDefaultVolume_num:*=param2;
			var aDefaultPlayOffsetInMs_num:*=param3;
			this.fSoundId_str=aSoundId_str;
			this.fDefaultVolume_num=aDefaultVolume_num;
			this.fDefaultPlayOffsetInMs_num=aDefaultPlayOffsetInMs_num;
			this.fSoundOn_bl=true;
			fChannels_sche_arr=new Array();
			fAuxiliarySounds_sndex_arr=new Array();
			fAuxiliarySoundsProbabilities_num_arr=new Array();
			try
			{
				this.fSound_snd=Sound(new (getDefinitionByName(this.fSoundId_str) as Class)());
			}
			catch (aError_err:Error)
			{
			}
			if (!fSound_snd)
			{
				this.fSound_snd=AssetsLibrary.getInstance().newSound(fSoundId_str);
				trace("[SoundEx]: SoundEx = > fSound_snd = " + fSound_snd);
			}
			return;
		} // end function

		public function play(param1:Number=0, param2:Number=0, param3:Number=0, param4:Number=-1):SoundChannelEx
		{
			var _loc_5:SoundChannelEx=null;
			trace("[SoundEx] play, sName = " + fSoundId_str);
			_loc_5=this.playSound(param1, param2, param3, param4);
			this.playAuxiliarySound(param1);
			return _loc_5;
		} // end function

		private function selectAuxiliarySound():SoundEx
		{
			var _loc_1:Number=NaN;
			var _loc_2:Number=NaN;
			var _loc_3:*=undefined;
			_loc_1=Math.random();
			_loc_2=0;
			_loc_3=0;
			while (_loc_3 < this.fAuxiliarySounds_sndex_arr.length)
			{

				_loc_2=_loc_2 + Number(this.fAuxiliarySoundsProbabilities_num_arr[_loc_3]);
				if (_loc_1 <= _loc_2)
				{
					return this.fAuxiliarySounds_sndex_arr[_loc_3];
				}
				_loc_3=_loc_3 + 1;
			}
			return null;
		} // end function

		private function stopAuxiliarySounds(param1:Number=0):void
		{
			var _loc_2:*=undefined;
			_loc_2=0;
			while (_loc_2 < this.fAuxiliarySounds_sndex_arr.length)
			{

				SoundEx(this.fAuxiliarySounds_sndex_arr[_loc_2]).stop(param1);
				_loc_2=_loc_2 + 1;
			}
			return;
		} // end function

		public function stop(param1:Number=0):void
		{
			var _loc_2:*=undefined;
			this.stopAuxiliarySounds();
			_loc_2=0;
			while (_loc_2 < this.fChannels_sche_arr.length)
			{

				SoundChannelEx(this.fChannels_sche_arr[_loc_2]).interruptPlaying(param1);
				_loc_2=_loc_2 + 1;
			}
			return;
		} // end function

		public function get soundOn():Boolean
		{
			return fSoundOn_bl;
		} // end function

		public function applyCommonVolumeGain(param1:Number, param2:Number=0):void
		{
			var _loc_3:int=0;
			this.applyVolumeGain(param1, param2);
			_loc_3=0;
			while (_loc_3 < this.fAuxiliarySounds_sndex_arr.length)
			{

				SoundEx(this.fAuxiliarySounds_sndex_arr[_loc_3]).applyCommonVolumeGain(param1, param2);
				_loc_3++;
			}
			return;
		} // end function

		private function playSound(param1:Number=0, param2:Number=0, param3:Number=0, param4:Number=-1):SoundChannelEx
		{
			var lSoundTransform_st:SoundTransform;
			var lSoundChannel_sch:SoundChannel;
			var lSoundChannel_sche:SoundChannelEx;
			var lVolume_num:Number;
			var aSeamlessVolumeIncreaseTimeInMs_num:*=param1;
			var aAdvancedPlayOffsetInMs_num:*=param2;
			var aSeamlessVolumeDecreaseTimeInMs_num:*=param3;
			var aVolume_num:*=param4;
			trace("SoundEx.playSound(): SOUND ID = " + this.fSoundId_str);
			lSoundTransform_st=new SoundTransform(0);
			lSoundChannel_sch=this.fSound_snd.play(this.fDefaultPlayOffsetInMs_num + aAdvancedPlayOffsetInMs_num, 0, lSoundTransform_st);
			try
			{
				lSoundChannel_sche=new SoundChannelEx(lSoundChannel_sch);
			}
			catch (err:Error)
			{
				lSoundChannel_sche=new SoundChannelEx(new SoundChannel());
			}
			lSoundChannel_sche.addEventListener(SoundChannelEx.EVENT_SOUND_CHANNEL_PLAYING_COMPLETED, this.onSoundChanelPlayingCompleted);
			lSoundChannel_sche.addEventListener(SoundChannelEx.EVENT_SOUND_CHANNEL_PLAYING_INTERRUPTED, this.onSoundChanelPlayingCompleted);
			this.fChannels_sche_arr.push(lSoundChannel_sche);
			lSoundChannel_sche.soundOn=this.soundOn;
			lVolume_num=aVolume_num == -1 ? (this.fDefaultVolume_num) : (aVolume_num);
			lSoundChannel_sche.setVolume(lVolume_num, aSeamlessVolumeIncreaseTimeInMs_num);
			if (aSeamlessVolumeDecreaseTimeInMs_num > 0)
			{
				lSoundChannel_sche.stopToPlay(aSeamlessVolumeDecreaseTimeInMs_num, this.fSound_snd.length - aSeamlessVolumeDecreaseTimeInMs_num - lSoundChannel_sche.soundChannel.position);
			}
			return lSoundChannel_sche;
		} // end function

		public function applyVolumeGain(param1:Number, param2:Number=0):void
		{
			var _loc_3:Number=NaN;
			_loc_3=param1 * this.soundVolume > 1 ? (1) : (param1 * this.soundVolume);
			this.setSoundVolume(_loc_3, param2);
			return;
		} // end function

		public function get soundVolume():Number
		{
			return this.fDefaultVolume_num;
		} // end function

		public function setSoundVolume(param1:Number, param2:Number=0):void
		{
			var _loc_3:*=undefined;
			var _loc_4:SoundChannelEx=null;
			this.fDefaultVolume_num=param1;
			_loc_3=0;
			while (_loc_3 < this.fChannels_sche_arr.length)
			{

				_loc_4=SoundChannelEx(this.fChannels_sche_arr[_loc_3]);
				if (!_loc_4.stopInProgress && !_loc_4.interruptionInProgress && !_loc_4.playingStopped && !_loc_4.playingInterrupted && !_loc_4.playingCompleted)
				{
					_loc_4.setVolume(param1, param2);
				}
				_loc_3=_loc_3 + 1;
			}
			return;
		} // end function

		public function addRandomAuxiliarySound(param1:String, param2:Number, param3:Number=1):SoundEx
		{
			var _loc_4:SoundEx=null;
			_loc_4=new SoundEx(param1, param3);
			this.fAuxiliarySounds_sndex_arr.push(_loc_4);
			fAuxiliarySoundsProbabilities_num_arr.push(param2);
			return _loc_4;
		} // end function

		public function set soundOn(param1:Boolean):void
		{
			var _loc_2:*=undefined;
			this.fSoundOn_bl=param1;
			_loc_2=0;
			while (_loc_2 < this.fAuxiliarySounds_sndex_arr.length)
			{

				SoundEx(this.fAuxiliarySounds_sndex_arr[_loc_2]).soundOn=this.fSoundOn_bl;
				_loc_2=_loc_2 + 1;
			}
			_loc_2=0;
			while (_loc_2 < this.fChannels_sche_arr.length)
			{

				SoundChannelEx(this.fChannels_sche_arr[_loc_2]).soundOn=this.fSoundOn_bl;
				_loc_2=_loc_2 + 1;
			}
			return;
		} // end function

		private function onSoundChanelPlayingCompleted(event:Event):void
		{
			var _loc_2:SoundChannelEx=null;
			var _loc_3:*=undefined;
			_loc_2=SoundChannelEx(event.target);
			_loc_3=0;
			while (_loc_3 < this.fChannels_sche_arr.length)
			{

				if (SoundChannelEx(this.fChannels_sche_arr[_loc_3]) == _loc_2)
				{
					this.fChannels_sche_arr.splice(_loc_3, 1);
					break;
				}
				_loc_3=_loc_3 + 1;
			}
			if (this.fChannels_sche_arr.length == 0)
			{
				this.onSoundPlayingCompleted();
			}
			return;
		} // end function

		private function onSoundPlayingCompleted():void
		{
			this.dispatchEvent(new Event(EVENT_SOUND_PLAYING_COMPLETED));
			return;
		} // end function

		public function get lengthInMs():Number
		{
			if (!this.fSound_snd)
			{
				throw Error("Cannot retrieve sound length before playing");
			}
			return this.fSound_snd.length - this.fDefaultPlayOffsetInMs_num;
		} // end function

		private function playAuxiliarySound(param1:Number=0):void
		{
			var _loc_2:SoundEx=null;
			_loc_2=this.selectAuxiliarySound();
			if (_loc_2)
			{
				_loc_2.play(param1);
			}
			return;
		} // end function

	}
}
